#include "Euler.h"
#include "Edge.h"
#include "Face.h"
#include "HalfEdge.h"
#include "Loop.h"
#include "Mesh.h"
#include "Point.h"
#include "Vertex.h"

Mesh* mvfs(const Point3D& pt) {
    auto mesh = new Mesh();
    auto face = new Face(mesh);
    auto loop = new Loop(face);
    auto vertex = new Vertex(pt, mesh);
    auto he = new HalfEdge;

    face->setOuterLoop(loop);
    loop->setHeadHe(he);
    he->setOrigin(vertex);
    he->setNext(he);
    he->setPrev(he);

    return mesh;
}
// 在一个 Loop 上添加一条边和一个新顶点
// Loop Make Edge and Vertex
// 在当前面的一个 Loop 上，从已有顶点出发：
// 创建一个新顶点；
// 创建一条新边；
// 更新相关的半边（HalfEdge）结构；
// 保持欧拉拓扑关系不变。
// he1 he2必须同一个出发顶点
void lmev(HalfEdge* he1, HalfEdge* he2, const Point3D& pt) {
    auto mesh = he1->loop()->face()->mesh();
    Vertex* v = new Vertex(pt, mesh);
    Edge* e = new Edge(mesh);

    auto he = he1;
    while (he != he2) {
        he->setOrigin(v);
        he = he->twin()->next();
    }

    addHalfEdge(e, he2->origin(), he1, PLUS);
    addHalfEdge(e, v, he2, PLUS);
}

Face* lmef(HalfEdge* he1, HalfEdge* he2) {
    auto mesh = he1->loop()->face()->mesh();

    auto face = new Face(mesh);
    auto loop = new Loop(face);
    auto edge = new Edge(mesh);

    face->setOuterLoop(loop);
    auto he = he1;
    while (he != he2) {
        he->setLoop(loop);
        he = he->next();
    }
    // 创建两个新的半边
    auto nhe1 = addHalfEdge(edge, he2->origin(), he1, MINUS);
    auto nhe2 = addHalfEdge(edge, he1->origin(), he2, PLUS);
    nhe1->prev()->setNext(nhe2);
    nhe2->prev()->setNext(nhe1);
    auto temp = nhe1->prev();
    nhe1->setPrev(nhe2->prev());
    nhe2->setPrev(temp);

    loop->setHeadHe(nhe1);
    he2->loop()->setHeadHe(nhe2);
    return face;
}

// 在一个环上添加一个halfedge
// 如果已经he不属于任何边，则把这个半边添加到边里
// 在环上添加一个新的边
HalfEdge* addHalfEdge(Edge* edge, Vertex* vertex, HalfEdge* he, HEdSign sign) {

    return nullptr;
}

// 从环上删除一个半边
// TODO: fix
HalfEdge* delHalfEdge(HalfEdge* he) {
    return nullptr;
}